package com.crm.common.agreement.common;

import com.alibaba.fastjson.JSONObject;
import com.ancun.netsign.client.NetSignClient;
import com.ancun.netsign.model.*;
import com.crm.common.agreement.entity.BO.TemplateParamsBO;
import com.crm.common.constant.Constants;
import com.crm.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Slf4j
@Component
public class AiQianUtils {

    @Value("${aiqianConfig.uri}")
    private String uri;

    @Value("${aiqianConfig.appId}")
    private String appId;

    @Value("${aiqianConfig.privateKey}")
    private String privateKey;

    @Value("${aiqianConfig.templateNotifyUrl}")
    private String templateNotifyUrl;

    @Value("${aiqianConfig.agreementNotifyUrl}")
    private String agreementNotifyUrl;

    @Value("${aiqianConfig.agreementRedirectUrl}")
    private String agreementRedirectUrl;

    @Value("${aiqianConfig.partyA}")
    private String partyA;



    /**
     *  添加企业用户
     */
    public String addEnterpriseUser(String enterpriseName,
                                    String businessLicenseNum,
                                    String corporationName,
                                    String corporationPhone,
                                    String corporationCard,
                                    String contactsName,
                                    String contactsPhone,
                                    String contactsCard){

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        UserInput userInput = new UserInput();
        String account = Constants.ORG_PREFIX +UUID.randomUUID().toString().replace("-","").substring(0,8);
        userInput.setAccount(account);
        userInput.setCompanyName(enterpriseName);
        userInput.setCreditCode(businessLicenseNum);
        userInput.setName(corporationName);
        userInput.setIdCard(corporationCard);
        userInput.setIdentifyMobile(corporationPhone);
        userInput.setIsSignPwdNotice(0);
        userInput.setIsNotice(0);
        userInput.setMobile(contactsPhone);
        userInput.setContactName(contactsName);
        userInput.setContactIdCard(contactsCard);
        userInput.setIdentifyType(2);
        ApiRespBody respBody = netSignClient.addEnterpriseUser(userInput);
        log.info("添加企业用户 respBody:"+JSONObject.toJSONString(respBody));
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return account;
        }else if(Integer.valueOf("100021").equals(respBody.getCode())){//用户已存在
            return account;
        }else{
            throw new CustomException("添加企业用户失败："+respBody.getMsg());
        }
    }


    /**
     * 创建印章
     * @param orgAccount
     * @return
     */
    public String createSeal(String orgAccount,String sealName){

        UserSealInput userSealInput = new UserSealInput();
        userSealInput.setAccount(orgAccount);
        userSealInput.setIsDefault(1);
        userSealInput.setSealName(" ");
        String sealNo = UUID.randomUUID().toString().replace("-","");
        System.out.println(sealNo);
        userSealInput.setSealNo(sealNo);
        userSealInput.setColor("FF0000");

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        ApiRespBody respBody = netSignClient.createSeal(userSealInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return sealNo;
        }else{
            throw new CustomException("创建印章失败："+respBody.getMsg());
        }
    }


    /**
     * 模板文件上传
     * @param file
     * @return
     */
    public String uploadTemplate(MultipartFile file, Integer isCover) throws IOException {

        List<FileDto> fileDtoList = new ArrayList();
        FileDto fileDto = new FileDto();
        fileDto.setFileName(file.getOriginalFilename());
        InputStream inputStream = file.getInputStream();
//        FileInputStream input = new FileInputStream(inputStream);
        fileDto.setFileInputStream(inputStream);
        fileDtoList.add(fileDto);
        MuiltFile muiltFile = new MuiltFile();
        muiltFile.setFileDtoList(fileDtoList);
        muiltFile.setParamFileName("image");
        String templateNo = "template-"+UUID.randomUUID().toString();
        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput templateEditInput = new TemplateEditInput();
        templateEditInput.setTemplateIdent(templateNo);
        templateEditInput.setIsCover(isCover);
        templateEditInput.setFile(fileDto);
        ApiRespBody respBody = netSignClient.uploadTemplateFile(templateEditInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return templateNo;
        }else{
            throw new CustomException("模板文件上传失败："+respBody.getMsg());
        }
    }


    /**
     * 模板文件上传
     * @param fileInputStream
     * @return
     */
    public String uploadTemplate(InputStream fileInputStream,String fileName, Integer isCover) throws IOException {

        List<FileDto> fileDtoList = new ArrayList();
        FileDto fileDto = new FileDto();
        fileDto.setFileName(fileName);
        InputStream inputStream = fileInputStream;
//        FileInputStream input = new FileInputStream(inputStream);
        fileDto.setFileInputStream(inputStream);
        fileDtoList.add(fileDto);
        MuiltFile muiltFile = new MuiltFile();
        muiltFile.setFileDtoList(fileDtoList);
        muiltFile.setParamFileName("image");
        String templateNo = "template-"+UUID.randomUUID().toString();
        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput templateEditInput = new TemplateEditInput();
        templateEditInput.setTemplateIdent(templateNo);
        templateEditInput.setIsCover(isCover);
        templateEditInput.setFile(fileDto);
        ApiRespBody respBody = netSignClient.uploadTemplateFile(templateEditInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return templateNo;
        }else{
            throw new CustomException("模板文件上传失败："+respBody.getMsg());
        }
    }

    /**
     * 编辑模板
     * @param templateNo
     * @return
     */
    public String openTemplate(String templateNo, List<TemplateParamsBO> paramsList) throws IOException{

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput input = new TemplateEditInput();
        input.setTemplateIdent(templateNo);
        input.setRedirectUrl(templateNotifyUrl);
        input.setHiddenBasic(1);
        List<TemplateControlDTO> controlData = new ArrayList<>();

        for(TemplateParamsBO params : paramsList){
            TemplateControlDTO dto = new TemplateControlDTO();
            dto.setDataType(params.getParamsType());
            dto.setDataKey(params.getParamsKey());
            dto.setNeedDrag(0);
            dto.setRequired(1);
            controlData.add(dto);
        }
        input.setControlData(controlData);

        ApiRespBody<String> respBody = netSignClient.getTemplateEditUrl(input);
        String s = respBody.getData();
        return s;

    }


    /**
     * 同步模板
     * @param templateNo
     * @return
     */
    public void syncTemplate(String templateNo){

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput input = new TemplateEditInput();
        input.setTemplateIdent(templateNo);
        ApiRespBody respBody = netSignClient.templateSync(input);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return ;
        }else{
            throw new CustomException("同步模板失败："+respBody.getMsg());
        }

    }

    /**
     * 撤销同步模板
     * @param templateNo
     * @return
     */
    public void cancelSyncTemplate(String templateNo){

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput input = new TemplateEditInput();
        input.setTemplateIdent(templateNo);
        ApiRespBody respBody = netSignClient.templateSyncCancel(input);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return ;
        }else{
            throw new CustomException("撤销同步模板失败："+respBody.getMsg());
        }

    }

    /**
     * 删除模板
     * @param templateNo
     * @return
     */
    public void delTemplate(String templateNo){

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput input = new TemplateEditInput();
        input.setTemplateIdent(templateNo);
        ApiRespBody respBody = netSignClient.templateDelete(input);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return ;
        }else{
            throw new CustomException("删除模板失败："+respBody.getMsg());
        }
    }

    /**
     * 模板详情
     * @param templateNo
     * @return
     */
    public OpenTemplateOutput templateInfo(String templateNo){

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        TemplateEditInput input = new TemplateEditInput();
        input.setPage(1);
        input.setRows(1);
        input.setTemplateIdent(templateNo);
        ApiRespBody<PageInfo<OpenTemplateOutput>> respBody = netSignClient.getOpenTemplateList(input);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            PageInfo<OpenTemplateOutput> pageInfo = respBody.getData();
            if(Optional.ofNullable(pageInfo).isPresent()){
                List<OpenTemplateOutput> outputList = pageInfo.getList();
                if(!CollectionUtils.isEmpty(outputList)){
                    return outputList.stream().findFirst().get();
                }
            }
            return null;
        }else{
            throw new CustomException("模板详情获取失败："+respBody.getMsg());
        }
    }






    /**
     * 创建合同-无参数
     */
    public boolean createContract(String contractNo, String templateNo,Map<String,String> params) {
        System.out.println(contractNo);
        ContractInput contractInput = new ContractInput();
//        contractInput.setNotifyUrl("http://localhost:8080/test/notify");
        //同步回调地址
//        contractInput.setRedirectUrl("http://localhost:8080/test/notify");
        contractInput.setContractNo(contractNo);
        contractInput.setContractName("合同");
        contractInput.setSignOrder(1);
        contractInput.setValidityTime(10);
        contractInput.setNotifyUrl(agreementNotifyUrl +"/"+contractNo);
        contractInput.setRedirectUrl(agreementRedirectUrl);
//        contractInput.setNotifyUrl(asignContractConfig.getNotifyUrl());

        Map<String, String> map = new HashMap<>(5);
        for(String key : params.keySet()){
            map.put(key,params.get(key));
        }

        List<ContractInput.Template> templates = new ArrayList<>();
        ContractInput.Template template = new ContractInput.Template();
        template.setTemplateNo(templateNo);
        template.setFillData(map);
        templates.add(template);
        contractInput.setTemplates(templates);

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        ApiRespBody respBody = netSignClient.createContract(contractInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return true;
        }else{
            throw new CustomException("创建合同失败："+respBody.getMsg());
        }
    }


    /**
     * 发起签署合同 - 无参数
     */
    public ContractOutput addSignerNoParams(String contractNo, String userAccount, List<Map<String,String>> subjectList,Integer validateType) {

        List<ContractUserInput> userInputList = new ArrayList<>();
        //用户签名设置
        ContractUserInput contractUserInput = new ContractUserInput();
        contractUserInput.setContractNo(contractNo);
        contractUserInput.setAccount(userAccount);
        contractUserInput.setSignOrder(1);
//        contractUserInput.setNeedPwdSignH5(1);
        //  2-无感知签章 3-有感知签章
        contractUserInput.setSignType(3);
        // 1:短信验证码签约 2：签约密码签约
        contractUserInput.setValidateType(validateType);
        contractUserInput.setIsNoticeComplete(0);
//        contractUserInput.setWaterMark(1);
        List<UserSignStrategyInput> strategyInputs = new ArrayList<>(5);
        UserSignStrategyInput userSignStrategyInput = new UserSignStrategyInput();
        userSignStrategyInput.setAttachNo(1);
        // 定位方式，2-坐标签章 3-关键字签章
        userSignStrategyInput.setLocationMode(4);
        userSignStrategyInput.setSignKey(partyA);
        strategyInputs.add(userSignStrategyInput);
        contractUserInput.setSignStrategyList(strategyInputs);
        userInputList.add(contractUserInput);

        for(Map<String,String> map : subjectList){
            //平台签章设置
            ContractUserInput contractUserInput2 = new ContractUserInput();
            contractUserInput2.setContractNo(contractNo);
            contractUserInput2.setSealNo(map.get("sealNo"));
            contractUserInput2.setAccount(map.get("account"));
            contractUserInput2.setIsNoticeComplete(0);
            contractUserInput2.setSignOrder(1);
            //  2-无感知签章 3-有感知签章
            contractUserInput2.setSignType(2);
            // 1:短信验证码签约 2：签约密码签约
            List<UserSignStrategyInput> strategyInputs2 = new ArrayList<>(5);
            UserSignStrategyInput userSignStrategyInput2 = new UserSignStrategyInput();
            userSignStrategyInput2.setAttachNo(1);
            // 定位方式，2-坐标签章 3-关键字签章
            userSignStrategyInput2.setLocationMode(4);
            userSignStrategyInput2.setSignKey(map.get("key"));
            strategyInputs2.add(userSignStrategyInput2);
            contractUserInput2.setSignStrategyList(strategyInputs2);
            userInputList.add(contractUserInput2);
        }

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        log.info("userInputList:"+JSONObject.toJSONString(userInputList));
        ApiRespBody<ContractOutput> respBody = netSignClient.addSigner(userInputList);
        log.info("respBody："+JSONObject.toJSONString(respBody));
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return respBody.getData();
        }else{
            throw new CustomException("发起签署合同失败："+respBody.getMsg());
        }
    }






    /**
     *  添加陌生用户（V2）
     */
    public void addStranger(String account,String mobile,String name){


        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        AddStrangerInput userInput = new AddStrangerInput();
        userInput.setAccount(account);
        userInput.setUserType(2);
        userInput.setName(name);
        userInput.setMobile(mobile);
        ApiRespBody respBody = netSignClient.addStranger(userInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return;
        }else if(Integer.valueOf("100021").equals(respBody.getCode())){//用户已存在
            return;
        }else{
            throw new CustomException("添加陌生用户失败："+respBody.getMsg());
        }
    }


    /**
     * 查询印章
     * @param account
     * @return
     */
    public UserSealOutput getUserSeals(String account,String sealNo){

        UserSealInput userSealInput = new UserSealInput();
        userSealInput.setAccount(account);
        userSealInput.setSealNo(sealNo);
        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        ApiRespBody<UserSealOutput> respBody = netSignClient.getUserSeals(userSealInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            UserSealOutput data = respBody.getData();
            return data;
        }else{
            throw new CustomException("创建平台爱签印章失败："+respBody.getMsg());
        }
    }


    /**
     * 查询合同状态
     * @param contractNo
     * @return
     */
    public Object queryContractStatus(String contractNo){

        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        ApiRespBody respBody = netSignClient.getContractStatus(contractNo);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return respBody.getData();
        }else{
            throw new CustomException("查询合同状态失败："+respBody.getMsg());
        }

    }


    /**
     * 获取合同信息
     * @param contractNo
     * @return
     */
    public Object getContract(String contractNo){
        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        ApiRespBody respBody = netSignClient.getContractInfo(contractNo);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            return respBody.getData();
        }else{
            throw new CustomException("获取合同信息失败："+respBody.getMsg());
        }
    }



    /**
     * 个人实名认证  运营商三要素实名
     * @param realname 姓名
     * @param idCard 身份证号码
     * @param phone 银行预留手机号码
     * @return
     */
    public AuthOutput personVerifyMobile3(String realname,String idCard,String phone){
        AuthInput authInput = new AuthInput();
        authInput.setRealName(realname);
        authInput.setIdCardNo(idCard);
        authInput.setMobile(phone);
        NetSignClient netSignClient = new NetSignClient(uri,appId, privateKey);
        ApiRespBody<AuthOutput> respBody = netSignClient.personVerifyMobile3(authInput);
        if(Integer.valueOf("100000").equals(respBody.getCode())){
            AuthOutput authOutput = respBody.getData();
            return authOutput;

        }else{
            throw new CustomException("个人实名认证失败："+respBody.getMsg());
        }
    }

}
